﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MathVolume
{
    public static class TransformationData
    {
        private class C_OutputData
        {
            private string _file;
            private int _count;
            private int[] _id;
            private double[] _x1;
            private double[] _y1;
            private double[] _x2;
            private double[] _y2;
            private double[] _v;
            private int[] _type;
//
            //== properties ================================
            public int Count
            {
                get
                {
                    return _count;
                }
            }

            //----------------------------------------------

            public int[] CollectionID
            {
                get
                {
                    return _id;
                }
            }

            //----------------------------------------------

            public double[] Collection_XLeft
            {
                get
                {
                    return _x1;
                }
            }

            //----------------------------------------------

            public double[] Collection_YLeft
            {
                get
                {
                    return _y1;
                }
            }

            //----------------------------------------------

            public double[] Collection_XCenter
            {
                get
                {
                    return _x2;
                }
            }

            //----------------------------------------------

            public double[] Collection_YCenter
            {
                get
                {
                    return _y2;
                }
            }

            //----------------------------------------------

            public double[] Collection_Volume
            {
                get
                {
                    return _v;
                }
            }

            //----------------------------------------------

            public int[] Collection_Type
            {
                get
                {
                    return _type;
                }
            }
            //----------------------------------------------
            //==============================================

            //== methods ===================================
            public C_OutputData(string in_file, int in_Count, int[] in_ID, double[] in_X1,
                                double[] in_Y1, double[] in_X2, double[] in_Y2,
                                double[] in_V, int[] in_type)
            {
                this._file = in_file;
                this._count = in_Count;
                this._id = in_ID;
                this._x1 = in_X1;
                this._y1 = in_Y1;
                this._x2 = in_X2;
                this._y2 = in_Y2;
                this._v = in_V;
                this._type = in_type;
            }
            //==========================================================================

            //==========================================================================
            public List<int> GetListType()
            {
                List<int> list_type = new List<int>();
                for (int i = 0; i < _type.Length; i++)
                {
                    list_type.Add(_type[i]);
                }
                return list_type;
            }
            //==========================================================================

            //===ВОЗВРАТ СПИСКА ТРЕУГОЛЬНИКОВ ==========================================
            public List<double[][]> GetTriangles()
            {
                // Вывод результатов:
                List<double[][]> resultTriangles = new List<double[][]>();

                for (int i = 0; i < this._count; i++)
                {
                    double[][] tempTriangle = new double[3][];
                    for (int j = 0; j < tempTriangle.Length; j++)
                    {
                        tempTriangle[j] = new double[2];
                    }

                    tempTriangle[0][0] = this._x1[i];
                    tempTriangle[0][1] = this._y1[i];

                    tempTriangle[1][0] = this._x2[i];
                    tempTriangle[1][1] = this._y2[i];

                    tempTriangle[2][0] = this._x1[i] + 2 * (this._x2[i] - this._x1[i]);
                    tempTriangle[2][1] = this._y1[i];

                    resultTriangles.Add(tempTriangle);
                }

                return resultTriangles;
            }
            //==========================================================================

            //==========================================================================
            public void WriteInTXT()
            {
                FileStream file = null;
                try
                {
                    file = new FileStream(this._file, FileMode.OpenOrCreate);
                }
                catch
                {
                    throw new Exception("Файл не удается создать или прочитать.");
                }
                try
                {
                    StreamWriter wr = new StreamWriter(file);
                    for (int i = 0; i < this._count; i++)
                    {
                        wr.Write(_id[i].ToString() + "\t" + this._x1[i].ToString() + "\t" +
                            _y1[i].ToString() + "\t" + this._x2[i].ToString() + "\t" +
                            _y2[i].ToString() + "\t" + this._v[i].ToString() + "\t" +
                            _type[i].ToString() + "\r\n");
                    }
                    wr.Close();
                }
                catch
                {
                    throw new Exception("Ошибка записи файла данных.");
                }
                file.Close();
            }
            //==========================================================================
        }

        private class C_InputData
        {
            private int _count;
            private int[] _id;
            private double[] _Xcenter;
            private double[] _V;
            private int[] _type;

            //== properties ================================
            public int[] CollectionID
            {
                get
                {
                    return this._id;
                }
            }
            //----------------------------------------------
            public int Count
            {
                get
                {
                    return this._count;
                }
            }
            //----------------------------------------------
            public double[] CollectionX_Centers
            {
                get
                {
                    return this._Xcenter;
                }
            }
            //----------------------------------------------
            public int[] CollectionTypes
            {
                get
                {
                    return this._type;
                }
            }
            //----------------------------------------------
            public double[] CollectionVolumes
            {
                get
                {
                    return this._V;
                }
            }
            //----------------------------------------------

            //== methods ===================================
            public C_InputData(string FileName)
            {
                this._count = CountRowsInTXT(FileName);
                this._id = new int[Count];
                this._type = new int[Count];
                this._V = new double[Count];
                this._Xcenter = new double[Count];
                ReadDataFromFile(FileName);
            }

            //----------------------------------------------

            private int CountRowsInTXT(string filename)
            {
                int num = 0;
                FileStream file = null;
                try
                {
                    file = new FileStream(filename, FileMode.Open);
                }
                catch
                {
                    throw new Exception("Не найден текстовый файл с данными.");
                }

                try
                {
                    StreamReader rd = new StreamReader(file);
                    string textfile = rd.ReadToEnd();
                    string[] tmpStr = textfile.Split('\n');
                    num = tmpStr.Length;
                    rd.Close();
                }
                catch
                {
                    throw new Exception("Ошибка чтения файла данных.");
                }
                file.Close();
                return num;
            }

            //----------------------------------------------

            private void ReadDataFromFile(string filename)
            {
                FileStream file = null;
                try
                {
                    file = new FileStream(filename, FileMode.Open);
                }
                catch
                {
                    throw new Exception("Не найден текстовый файл с данными.");
                }

                try
                {
                    StreamReader rd = new StreamReader(file);
                    string textfile = rd.ReadToEnd();
                    string[] sep1 = new string[1];
                    sep1[0] = "\r\n";
                    string[] rows = textfile.Split(sep1, StringSplitOptions.None);
                    int num = rows.Length;
                    sep1 = new string[2];
                    sep1[0] = " ";
                    sep1[1] = "\t";
                    for (int i = 0; i < num; i++)
                    {
                        string[] ValuesInRow = rows[i].Split(sep1, StringSplitOptions.None);
                        _id[i] = int.Parse(ValuesInRow[0]);
                        _Xcenter[i] = double.Parse(ValuesInRow[1]);
                        _V[i] = double.Parse(ValuesInRow[2]);
                        _type[i] = int.Parse(ValuesInRow[3]);
                    }
                    rd.Close();
                }
                catch
                {
                    throw new Exception("Ошибка чтения файла данных.");
                }
                file.Close();
            }

            //----------------------------------------------
            //==============================================
        }

        private class MassiVe
        {
            public double[] mX;
            public double[] mY;
            public int count;
        }

        //----------------------------------------------------------------
        public static bool sthFunc(ref List<double[][]> triangles, 
                                    ref List<int> operations)
        {
            try
            {
                C_OutputData output = TransformerData("");
                triangles = output.GetTriangles();
                operations = output.GetListType();
                return true;
            }
            catch
            {
                return false;
            }
        }
        //----------------------------------------------------------------
        //---- номер максимального ---------------------------------------
        private static int numMax(double[] Massive, int count, bool[] NoExitPoint)
        {
            double max = -100000;
            int num_max = -100000;
            for (int i = 0; i < count; i++)
            {
                if (NoExitPoint[i] == true)
                {
                    if (Massive[i] > max)
                    {
                        max = Massive[i];
                        num_max = i;
                    }
                }
            }
            return num_max;
        }

        //----------------------------------------------------------------
        //------------------- номер минимального -------------------------
        private static int numMin(double[] Massive, int count, bool[] NoExitPoint)
        {
            double min = -100000;
            int num_min = -1;
            for (int i = 0; i < count; i++)
            {
                if (NoExitPoint[i] == true)
                {
                    if (min == -100000)
                    {
                        min = Massive[i];
                        num_min = i;
                    }
                    if (Massive[i] < min)
                    {
                        min = Massive[i];
                        num_min = i;
                    }
                }
            }
            return num_min;
        }

        //----------------------------------------------------------------
        //---------- наличие пересечения двух прямых ---------------------
        private static bool Peresechenie(double k1, double b1, double k2, double b2,
                                                double xMin, double xMax)
        {
            if (k1 == k2) return false;

            double x0 = (b2 - b1) / (k1 - k2);
            if ((x0 >= xMin) && (x0 <= xMax)) return true;
            else return false;
        }

        //----------------------------------------------------------------
        //---------- значение X пересечения двух прямых ------------------
        private static double X_Peresechenie(double k1, double b1, double k2, double b2)
        {
            double x0 = (b2 - b1) / (k1 - k2);
            return x0;
        }

        //----------------------------------------------------------------
        //-- номер точки после которой имеется пересечение с укладкой ----
        private static int NumPointPeresechen(double[] carcasX, double[] carcasY,
                int carcasCount, double x1, double y1, double x2, double y2)
        {
            int num = -1;
            double k1 = k_FunctionLine(x1, y1, x2, y2);
            double b1 = b_FunctionLine(x1, y1, x2, y2);

            for (int i = 0; i < carcasCount - 1; i++)
            {
                double xMax, xMin;
                double carcasX1 = carcasX[i], carcasY1 = carcasY[i];
                double carcasX2 = carcasX[i + 1], carcasY2 = carcasY[i + 1];
                if (carcasX1 <= carcasX2)
                {
                    xMax = carcasX2;
                    xMin = carcasX1;
                }
                else
                {
                    xMax = carcasX1;
                    xMin = carcasX2;
                }
                double k2 = k_FunctionLine(carcasX1, carcasY1, carcasX2, carcasY2);
                double b2 = b_FunctionLine(carcasX1, carcasY1, carcasX2, carcasY2);

                if (Peresechenie(k1, b1, k2, b2, xMin, xMax))
                {
                    num = i;
                    break;
                }
            }
            return num;
        }

        //================================================================

        //===================функция нахождения min H======================================
        private static double minH(double[] carcasX, double[] carcasY, int carcasCount, double x)
        {
            double h = 0;
            for (int i = 0; i < carcasCount - 1; i++)
            {
                if (carcasX[i] == x)
                {
                    h = carcasY[i];
                    break;
                }
                if (carcasX[i + 1] == x)
                {
                    h = carcasY[i + 1];
                    break;
                }
                if (x > carcasX[i] && x < carcasX[i + 1])
                {
                    double k = k_FunctionLine(carcasX[i], carcasY[i], carcasX[i + 1], carcasY[i + 1]);
                    double b = b_FunctionLine(carcasX[i], carcasY[i], carcasX[i + 1], carcasY[i + 1]);
                    h = k * x + b;
                    break;
                }
            }
            return h;
        }
        //=================================================================================

        //=================================================================================
        private static double[] NeRavnbiX(double[] ADDcarcasX, int n)
        {
            double Rand = 0.0001;
            double[] tmp = new double[n];
            for (int i = 0; i < n; i++)
            {
                tmp[i] = ADDcarcasX[i];
            }
            for (int i = 0; i < n - 1; i++)
            {
                for (int j = i + 1; j < n; j++)
                {
                    if (tmp[i] == tmp[j])
                    {
                        tmp[j] += Rand;
                    }
                }
            }
            return tmp;
        }
        //=================================================================================

        //===================функция преобразования входных данных во выходные=============
        private static C_OutputData TransformerData(string pathExe)
        {
            string In_file = pathExe + "Input.txt";
            string Out_file = pathExe + "Output.txt";
            C_OutputData output = null;
            C_InputData input = new C_InputData(In_file);
            double A = 50;               //ширина штабеля
            int Count = input.Count;
            int[] ID = input.CollectionID;
            double[] X1= new double[Count];
            double[] Y1= new double[Count];
            double[] X2= new double[Count];
            double[] Y2= new double[Count];
            double[] V= input.CollectionVolumes;
            int[] type= input.CollectionTypes;
            MassiVe ZZZ = new MassiVe();
            
            double H = 25.0;
            int carcasCount = 0;
            double[] carcasX = new double[carcasCount];
            double[] carcasY = new double[carcasCount];
            double Vz = 0, Vp = 0, V_ = 0, oldV = 0, deltaV = 0;
            double[] ADDcarcasX = new double[3];
            double[] ADDcarcasY = new double[3];

            for (int i = 0; i < Count; i++)
            {
                double delta = 0.01;
                double h = minH(carcasX, carcasY, carcasCount, input.CollectionX_Centers[i]);
                if (input.CollectionTypes[i] == 1)
                {
                    h += delta;
                    ADDcarcasX = new double[3];
                    ADDcarcasY = new double[3];
                    for (double j = h; j < H; j += delta)
                    {
                        Vz = 0; Vp = 0; V_ = 0; oldV = 0; deltaV = 0;
                        int num1 = NumPointPeresechen(carcasX, carcasY, carcasCount, input.CollectionX_Centers[i] - j, 0, input.CollectionX_Centers[i], j);
                        int num2 = NumPointPeresechen(carcasX, carcasY, carcasCount, input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + j, 0);
                        if (num1 == -1 && num2 == -1)
                        {
                            if (carcasCount > 0)
                            {
                                //есть пересечение целиком под укладкой
                                if (carcasX[0] > input.CollectionX_Centers[i] - j && carcasX[0] < input.CollectionX_Centers[i] + j)
                                {
                                    oldV = deltaV;
                                    Vz = input.CollectionVolumes[i];
                                    Vp = VolumeFigure_UKLADKA(carcasX, carcasY, carcasCount, A);
                                    ADDcarcasX[0] = input.CollectionX_Centers[i] - j;
                                    ADDcarcasX[1] = input.CollectionX_Centers[i];
                                    ADDcarcasX[2] = input.CollectionX_Centers[i] + j;

                                    ADDcarcasY[0] = 0;
                                    ADDcarcasY[1] = j;
                                    ADDcarcasY[2] = 0;
                                    V_ = VolumeFigure_UKLADKA(ADDcarcasX, ADDcarcasY, 3,A);
                                    deltaV = V_ - Vp;
                                }
                                //нет пересечения
                                else
                                {
                                    oldV = deltaV;
                                    Vp = 0;
                                    ADDcarcasX[0] = input.CollectionX_Centers[i] - j;
                                    ADDcarcasX[1] = input.CollectionX_Centers[i];
                                    ADDcarcasX[2] = input.CollectionX_Centers[i] + j;

                                    ADDcarcasY[0] = 0;
                                    ADDcarcasY[1] = j;
                                    ADDcarcasY[2] = 0;
                                    V_ = VolumeFigure_UKLADKA(ADDcarcasX, ADDcarcasY, 3,A);
                                    deltaV = V_ - Vp;
                                }
                            }
                            //первая закладка----------------------------------------------------
                            if (carcasCount == 0)
                            {
                                oldV = deltaV;
                                Vz = input.CollectionVolumes[i];
                                Vp = 0;
                                ADDcarcasX[0] = input.CollectionX_Centers[i] - j;
                                ADDcarcasX[1] = input.CollectionX_Centers[i];
                                ADDcarcasX[2] = input.CollectionX_Centers[i] + j;

                                ADDcarcasY[0] = 0;
                                ADDcarcasY[1] = j;
                                ADDcarcasY[2] = 0;
                                V_ = VolumeFigure_UKLADKA(ADDcarcasX, ADDcarcasY, 3,A);
                                deltaV = V_ - Vp;
                            }
                        }
                        if (num1 != -1 && num2 == -1) //закладка справа
                        {
                            oldV = deltaV;
                            ADDcarcasX[0] = input.CollectionX_Centers[i] - j;
                            ADDcarcasX[1] = input.CollectionX_Centers[i];
                            ADDcarcasX[2] = input.CollectionX_Centers[i] + j;

                            ADDcarcasY[0] = 0;
                            ADDcarcasY[1] = j;
                            ADDcarcasY[2] = 0;
                            V_ = VolumeFigure_UKLADKA(ADDcarcasX, ADDcarcasY, 3,A);
                            double x1 = carcasX[num1];
                            double y1 = carcasY[num1];
                            double x2 = carcasX[num1 + 1];
                            double y2 = carcasY[num1 + 1];
                            double k1 = k_FunctionLine(x1, y1, x2, y2);
                            double b1 = b_FunctionLine(x1, y1, x2, y2);
                            double k2 = k_FunctionLine(input.CollectionX_Centers[i] - j, 0, input.CollectionX_Centers[i], j);
                            double b2 = b_FunctionLine(input.CollectionX_Centers[i] - j, 0, input.CollectionX_Centers[i], j);
                            double xPeres = X_Peresechenie(k1, b1, k2, b2);
                            double yPeres = k1 * xPeres + b1;
                            double[] perekX = new double[2 + carcasCount - num1 - 1];
                            double[] perekY = new double[2 + carcasCount - num1 - 1];
                            perekX[0] = input.CollectionX_Centers[i] - j;
                            perekY[0] = 0;
                            perekX[1] = xPeres;
                            perekY[1] = yPeres;
                            for (int i1 = 0; i1 < carcasCount - num1 - 1; i1++)
                            {
                                perekX[i1 + 2] = carcasX[i1 + num1 + 1];
                                perekY[i1 + 2] = carcasY[i1 + num1 + 1];
                            }
                            Vp = VolumeFigure_UKLADKA(perekX, perekY, 2 + carcasCount - num1 - 1,A);
                            deltaV = V_ - Vp;

                            ADDcarcasX[0] = xPeres;
                            ADDcarcasX[1] = input.CollectionX_Centers[i];
                            ADDcarcasX[2] = input.CollectionX_Centers[i] + j;

                            ADDcarcasY[0] = yPeres;
                            ADDcarcasY[1] = j;
                            ADDcarcasY[2] = 0;
                        }
                        if (num1 == -1 && num2 != -1) //закладка слева
                        {
                            oldV = deltaV;
                            ADDcarcasX[0] = input.CollectionX_Centers[i] - j;
                            ADDcarcasX[1] = input.CollectionX_Centers[i];
                            ADDcarcasX[2] = input.CollectionX_Centers[i] + j;

                            ADDcarcasY[0] = 0;
                            ADDcarcasY[1] = j;
                            ADDcarcasY[2] = 0;
                            V_ = VolumeFigure_UKLADKA(ADDcarcasX, ADDcarcasY, 3,A);
                            double x1 = carcasX[num2];
                            double y1 = carcasY[num2];
                            double x2 = carcasX[num2 + 1];
                            double y2 = carcasY[num2 + 1];
                            double k1 = k_FunctionLine(x1, y1, x2, y2);
                            double b1 = b_FunctionLine(x1, y1, x2, y2);
                            double k2 = k_FunctionLine(input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + j, 0);
                            double b2 = b_FunctionLine(input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + j, 0);
                            double xPeres = X_Peresechenie(k1, b1, k2, b2);
                            double yPeres = k1 * xPeres + b1;
                            double[] perekX = new double[2 + num2 + 1];
                            double[] perekY = new double[2 + num2 + 1];

                            for (int i1 = 0; i1 < num2 + 1; i1++)
                            {
                                perekX[i1] = carcasX[i1];
                                perekY[i1] = carcasY[i1];
                            }
                            perekX[num2 + 1] = xPeres;
                            perekY[num2 + 1] = yPeres;
                            perekX[num2 + 2] = input.CollectionX_Centers[i] + j;
                            perekY[num2 + 2] = 0;
                            Vp = VolumeFigure_UKLADKA(perekX, perekY, 2 + num2 + 1,A);
                            deltaV = V_ - Vp;

                            ADDcarcasX[0] = input.CollectionX_Centers[i] - j;
                            ADDcarcasX[1] = input.CollectionX_Centers[i];
                            ADDcarcasX[2] = xPeres;

                            ADDcarcasY[0] = 0;
                            ADDcarcasY[1] = j;
                            ADDcarcasY[2] = yPeres;

                        }
                        if (num1 != -1 && num2 != -1) //закладка посеред
                        {
                            oldV = deltaV;
                            ADDcarcasX[0] = input.CollectionX_Centers[i] - j;
                            ADDcarcasX[1] = input.CollectionX_Centers[i];
                            ADDcarcasX[2] = input.CollectionX_Centers[i] + j;

                            ADDcarcasY[0] = 0;
                            ADDcarcasY[1] = j;
                            ADDcarcasY[2] = 0;
                            V_ = VolumeFigure_UKLADKA(ADDcarcasX, ADDcarcasY, 3,A);

                            double[] perekX = new double[2 + 2 + num2 - num1];
                            double[] perekY = new double[2 + 2 + num2 - num1];

                            perekX[0] = input.CollectionX_Centers[i] - j;
                            perekY[0] = 0;

                            double x1 = carcasX[num1];
                            double y1 = carcasY[num1];
                            double x2 = carcasX[num1 + 1];
                            double y2 = carcasY[num1 + 1];

                            double k1 = k_FunctionLine(x1, y1, x2, y2);
                            double b1 = b_FunctionLine(x1, y1, x2, y2);
                            double k2 = k_FunctionLine(input.CollectionX_Centers[i] - j, 0, input.CollectionX_Centers[i], j);
                            double b2 = b_FunctionLine(input.CollectionX_Centers[i] - j, 0, input.CollectionX_Centers[i], j);
                            double xPeres = X_Peresechenie(k1, b1, k2, b2);
                            double yPeres = k1 * xPeres + b1;

                            perekX[1] = xPeres;
                            perekY[1] = yPeres;

                            ADDcarcasX[0] = xPeres;
                            ADDcarcasX[1] = input.CollectionX_Centers[i];

                            ADDcarcasY[0] = yPeres;
                            ADDcarcasY[1] = j;

                            for (int i1 = num1 + 1; i1 <= num2; i1++)
                            {
                                perekX[i1 - num1 - 1 + 2] = carcasX[i1];
                                perekY[i1 - num1 - 1 + 2] = carcasY[i1];
                            }

                            x1 = carcasX[num2];
                            y1 = carcasY[num2];
                            x2 = carcasX[num2 + 1];
                            y2 = carcasY[num2 + 1];

                            ///
                            k1 = k_FunctionLine(x1, y1, x2, y2);
                            b1 = b_FunctionLine(x1, y1, x2, y2);
                            k2 = k_FunctionLine(input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + j, 0);
                            b2 = b_FunctionLine(input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + j, 0);
                            xPeres = X_Peresechenie(k1, b1, k2, b2);
                            yPeres = k1 * xPeres + b1;
                            ////

                            perekX[2 + num2 - num1] = xPeres;
                            perekY[2 + num2 - num1] = yPeres;

                            ADDcarcasX[2] = xPeres;
                            ADDcarcasY[2] = yPeres;

                            perekX[3 + num2 - num1] = input.CollectionX_Centers[i] + j;
                            perekY[3 + num2 - num1] = 0;

                            Vp = VolumeFigure_UKLADKA(perekX, perekY, 2 + 2 + num2 - num1,A);
                            deltaV = V_ - Vp;
                        }
                        //if((oldV<=input.GetV()[i] && deltaV>=input.GetV()[i])||(oldV>=input.GetV()[i] && deltaV>=input.GetV()[i]))
                        if ((oldV <= input.CollectionVolumes[i] && deltaV >= input.CollectionVolumes[i]))
                        {
                            ZZZ=DeleteE__inMassive(num1, num2, carcasX, carcasY, carcasCount, ADDcarcasX, ADDcarcasY, 1);
                            carcasCount = ZZZ.count;
                            carcasX = new double[carcasCount];
                            carcasY = new double[carcasCount];
                            for (int kk = 0; kk < carcasCount; kk++)
                            {

                                carcasX[kk] = ZZZ.mX[kk];
                                carcasY[kk] = ZZZ.mY[kk];
                            }
                            X1[i] = input.CollectionX_Centers[i] - j;
                            Y1[i] = 0;
                            X2[i] = input.CollectionX_Centers[i];
                            Y2[i] = j;
                            break;
                        }
                    }
                }
                if (input.CollectionTypes[i] == 2) //забор
                {
                    double Xleft = 0, Yleft = 0;
                    h -= delta;
                    Vz = 0; Vp = 0; V_ = 0; oldV = 0; deltaV = 0;
                    for (double j = h; j >= 0; j -= delta)
                    {
                        //if(j==h)j-=delta;
                        if (j < 0) break;
                        int num1 = NumPointPeresechen(carcasX, carcasY, carcasCount, 0, j + input.CollectionX_Centers[i], input.CollectionX_Centers[i], j);
                        int num2 = NumPointPeresechen(carcasX, carcasY, carcasCount, input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + 100, j + 100);
                        ADDcarcasX = new double[num2 - num1 + 3];
                        ADDcarcasY = new double[num2 - num1 + 3];

                        double x1 = carcasX[num1];
                        double y1 = carcasY[num1];
                        double x2 = carcasX[num1 + 1];
                        double y2 = carcasY[num1 + 1];
                        double k1 = k_FunctionLine(x1, y1, x2, y2);
                        double b1 = b_FunctionLine(x1, y1, x2, y2);
                        double k2 = k_FunctionLine(0, j + input.CollectionX_Centers[i], input.CollectionX_Centers[i], j);
                        double b2 = b_FunctionLine(0, j + input.CollectionX_Centers[i], input.CollectionX_Centers[i], j);
                        double xPeres = X_Peresechenie(k1, b1, k2, b2);
                        Xleft = xPeres;
                        double yPeres = k1 * xPeres + b1;
                        Yleft = yPeres;
                        ADDcarcasX[0] = xPeres;
                        ADDcarcasY[0] = yPeres;
                        for (int i1 = 0; i1 < num2 - num1; i1++)
                        {
                            ADDcarcasX[i1 + 1] = carcasX[num1 + i1 + 1];
                            ADDcarcasY[i1 + 1] = carcasY[num1 + i1 + 1];
                        }
                        x1 = carcasX[num2];
                        y1 = carcasY[num2];
                        x2 = carcasX[num2 + 1];
                        y2 = carcasY[num2 + 1];
                        k1 = k_FunctionLine(x1, y1, x2, y2);
                        b1 = b_FunctionLine(x1, y1, x2, y2);
                        k2 = k_FunctionLine(input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + 500, j + 500);
                        b2 = b_FunctionLine(input.CollectionX_Centers[i], j, input.CollectionX_Centers[i] + 500, j + 500);
                        xPeres = X_Peresechenie(k1, b1, k2, b2);
                        yPeres = k1 * xPeres + b1;

                        if (yPeres > Yleft)
                        {
                            Yleft = yPeres;
                            Xleft = input.CollectionX_Centers[i] - Math.Abs(xPeres - input.CollectionX_Centers[i]);
                        }

                        ADDcarcasX[num2 - num1 + 1] = xPeres;
                        ADDcarcasY[num2 - num1 + 1] = yPeres;
                        ADDcarcasX[num2 - num1 + 2] = input.CollectionX_Centers[i];
                        ADDcarcasY[num2 - num1 + 2] = j;
                        oldV = Vp;
                        double[] ADDcarcasX1 = NeRavnbiX(ADDcarcasX, num2 - num1 + 3);
                        Vp = VolumeFigure_ZABOR(ADDcarcasX1, ADDcarcasY, num2 - num1 + 3,A);
                        if ((oldV <= input.CollectionVolumes[i] && Vp >= input.CollectionVolumes[i]))
                        {
                            ZZZ = DeleteE__inMassive(num1, num2, carcasX, carcasY, carcasCount, ADDcarcasX, ADDcarcasY, 2);
                            carcasCount = ZZZ.count;
                            carcasX = new double[carcasCount];
                            carcasY = new double[carcasCount];
                            for (int kk = 0; kk < carcasCount; kk++)
                            {

                                carcasX[kk] = ZZZ.mX[kk];
                                carcasY[kk] = ZZZ.mY[kk];
                            }

                            double tmpH = 20;
                            X1[i] = input.CollectionX_Centers[i] - (tmpH - j);// / Math.Pow(3.0, 0.5);
                            Y1[i] = tmpH;
                            X2[i] = input.CollectionX_Centers[i];
                            Y2[i] = j;
                            break;
                        }

                    }
                }
            }
            output = new C_OutputData(Out_file, Count, ID, X1, Y1, X2, Y2, V, type);

            return output;
        }
        //=================================================================================

        //====================удалить элементы в массиве с конца до значания Е=============
        private static MassiVe DeleteE__inMassive(int num1, int num2, double[] carcasX, double[] carcasY,
                                        int carcasCount, double[] ADDcarcasX, double[] ADDcarcasY, int type)
        {
            MassiVe ZZZ = new MassiVe();
            if (num1 == -1 && num2 == -1)
            {
                if (carcasCount == 0)
                {
                    ZZZ.mX = new double[3];
                    ZZZ.mY = new double[3];
                    ZZZ.count = 3;
                    ZZZ.mX[0] = ADDcarcasX[0];
                    ZZZ.mX[1] = ADDcarcasX[1];
                    ZZZ.mX[2] = ADDcarcasX[2];

                    ZZZ.mY[0] = ADDcarcasY[0];
                    ZZZ.mY[1] = ADDcarcasY[1];
                    ZZZ.mY[2] = ADDcarcasY[2];
                    return ZZZ;
                }
                if (carcasCount > 0)
                {
                    //есть пересечение целиком под укладкой
                    if (carcasX[0] > ADDcarcasX[0] && carcasX[0] < ADDcarcasX[2])
                    {
                        ZZZ.mX = new double[3];
                        ZZZ.mY = new double[3];
                        ZZZ.count = 3;
                        ZZZ.mX[0] = ADDcarcasX[0];
                        ZZZ.mX[1] = ADDcarcasX[1];
                        ZZZ.mX[2] = ADDcarcasX[2];

                        ZZZ.mY[0] = ADDcarcasY[0];
                        ZZZ.mY[1] = ADDcarcasY[1];
                        ZZZ.mY[2] = ADDcarcasY[2];
                        return ZZZ;
                    }
                    //каркас справа от укладки
                    if (carcasX[0] > ADDcarcasX[2])
                    {
                        ZZZ.mX = new double[3 + carcasCount];
                        ZZZ.mY = new double[3 + carcasCount];
                        ZZZ.count = 3 + carcasCount;
                        ZZZ.mX[0] = ADDcarcasX[0];
                        ZZZ.mX[1] = ADDcarcasX[1];
                        ZZZ.mX[2] = ADDcarcasX[2];

                        ZZZ.mY[0] = ADDcarcasY[0];
                        ZZZ.mY[1] = ADDcarcasY[1];
                        ZZZ.mY[2] = ADDcarcasY[2];
                        for (int i = 0; i < carcasCount; i++)
                        {
                            ZZZ.mX[i + 3] = carcasX[i];
                            ZZZ.mY[i + 3] = carcasY[i];
                        }
                        return ZZZ;
                    }
                    //каркас слева от укладки
                    if (carcasX[carcasCount - 1] < ADDcarcasX[0])
                    {
                        ZZZ.mX = new double[3 + carcasCount];
                        ZZZ.mY = new double[3 + carcasCount];
                        ZZZ.count = 3 + carcasCount;
                        for (int i = 0; i < carcasCount; i++)
                        {
                            ZZZ.mX[i] = carcasX[i];
                            ZZZ.mY[i] = carcasY[i];
                        }
                        ZZZ.mX[carcasCount] = ADDcarcasX[0];
                        ZZZ.mX[carcasCount + 1] = ADDcarcasX[1];
                        ZZZ.mX[carcasCount + 2] = ADDcarcasX[2];

                        ZZZ.mY[carcasCount + 0] = ADDcarcasY[0];
                        ZZZ.mY[carcasCount + 1] = ADDcarcasY[1];
                        ZZZ.mY[carcasCount + 2] = ADDcarcasY[2];
                        return ZZZ;
                    }
                }
            }
            if (num1 != -1 && num2 == -1)
            {
                ZZZ.count = num1 + 1 + 3;
                ZZZ.mX = new double[ZZZ.count];
                ZZZ.mY = new double[ZZZ.count];
                for (int i = 0; i < num1 + 1; i++)
                {
                    ZZZ.mX[i] = carcasX[i];
                    ZZZ.mY[i] = carcasY[i];
                }
                ZZZ.mX[num1 + 1] = ADDcarcasX[0];
                ZZZ.mX[num1 + 2] = ADDcarcasX[1];
                ZZZ.mX[num1 + 3] = ADDcarcasX[2];

                ZZZ.mY[num1 + 1] = ADDcarcasY[0];
                ZZZ.mY[num1 + 2] = ADDcarcasY[1];
                ZZZ.mY[num1 + 3] = ADDcarcasY[2];
                return ZZZ;
            }
            if (num1 == -1 && num2 != -1)
            {
                ZZZ.count = carcasCount - num2 - 1 + 3;
                ZZZ.mX = new double[ZZZ.count];
                ZZZ.mY = new double[ZZZ.count];
                ZZZ.mX[0] = ADDcarcasX[0];
                ZZZ.mX[1] = ADDcarcasX[1];
                ZZZ.mX[2] = ADDcarcasX[2];

                ZZZ.mY[0] = ADDcarcasY[0];
                ZZZ.mY[1] = ADDcarcasY[1];
                ZZZ.mY[2] = ADDcarcasY[2];
                for (int i = 3; i < ZZZ.count; i++)
                {
                    ZZZ.mX[i] = carcasX[i - 3 + num2 + 1];
                    ZZZ.mY[i] = carcasY[i - 3 + num2 + 1];
                }
                return ZZZ;
            }
            if (num1 != -1 && num2 != -1)
            {
                ZZZ.count = carcasCount + 3 - (num2 - num1);
                ZZZ.mX = new double[ZZZ.count];
                ZZZ.mY = new double[ZZZ.count];
                for (int i = 0; i < num1 + 1; i++)
                {
                    ZZZ.mX[i] = carcasX[i];
                    ZZZ.mY[i] = carcasY[i];
                }
                ZZZ.mX[num1 + 1] = ADDcarcasX[0];

                ZZZ.mY[num1 + 1] = ADDcarcasY[0];
                if (type == 1)
                {
                    ZZZ.mX[num1 + 2] = ADDcarcasX[1];
                    ZZZ.mY[num1 + 2] = ADDcarcasY[1];
                    ZZZ.mY[num1 + 3] = ADDcarcasY[2];
                    ZZZ.mX[num1 + 3] = ADDcarcasX[2];
                }
                else
                {
                    ZZZ.mX[num1 + 2] = ADDcarcasX[num2 - num1 + 2];
                    ZZZ.mY[num1 + 2] = ADDcarcasY[num2 - num1 + 2];
                    ZZZ.mY[num1 + 3] = ADDcarcasY[num2 - num1 + 1];
                    ZZZ.mX[num1 + 3] = ADDcarcasX[num2 - num1 + 1];
                }


                for (int i = num1 + 4; i < ZZZ.count; i++)
                {
                    ZZZ.mX[i] = carcasX[i - (num1 + 4) + num2 + 1];
                    ZZZ.mY[i] = carcasY[i - (num1 + 4) + num2 + 1];
                }
                return ZZZ;
            }
            return ZZZ;
        }
        //=================================================================================

        //====================расчет Ve = V1_t*2 +V2_t верхней фигуры============================
        private static double elementarVolume_ZABOR_TOP(double x1, double x2, double y1, double y2, double y3, double a)
        {
            //eV = eV1+eV2+eV3 = eV1*2 + eV3 
            double v1 = eVolume1_3_ZABOR_TOP(x1, x2, y1, y2, y3, a, x2) - eVolume1_3_ZABOR_TOP(x1, x2, y1, y2, y3, a, x1);
            double v2 = eVolume2_ZABOR_TOP(x1, x2, y1, y2, y3, a, x2) - eVolume2_ZABOR_TOP(x1, x2, y1, y2, y3, a, x1);
            double v = v2 + 2 * v1;
            return v;
        }
        //=======================================================================================

        //====================объем V2_t======================================
        private static double eVolume2_ZABOR_TOP(double x1, double x2, double y1, double y2, double y3, double a, double x)
        {
            double v2 = 2.0 * (y2 - y3) * x * x * x / (3.0 * (x2 - x1)) - (y2 - y3) * x1 * x * x / (x2 - x1) + 0.5 * (a - 2 * y1) * x * x - (y2 - y1) * x * x -
                        x1 * (a - 2 * y1) * x - x1 * (y2 - y3) * (x - x1) * (x - x1) / (x2 - x1) + 2.0 * (y2 - y1) * x1 * x +
                        (y2 - y1) * (y2 - y3) * (x - x1) * (x - x1) / (x2 - x1) - 2.0 * (y2 - y1) * (y2 - y1) * x + (a - 2 * y1) * (y2 - y1) * x;
            return v2;
        }
        //=======================================================================================

        //====================объем V1_t======================================
        private static double eVolume1_3_ZABOR_TOP(double x1, double x2, double y1, double y2, double y3, double a, double x)
        {
            double v1 = 0.5 * ((y2 - y1) * (y2 - y1) * x + (y3 - y2) * (x - x1) * (x - x1) * (x - x1) / (3.0 * (x2 - x1)) +
                                                            (y2 - y1) * (y3 - y2) * (x - x1) * (x - x1) / (x2 - x1));
            return v1;
        }
        //=======================================================================================

        //====================расчет Ve = V1_b*2 +V2_b нижней фигуры======================================
        private static double elementarVolume_ZABOR_BOTTOM(double x1, double x2, double y1, double y2, double y3, double a)
        {
            //eV = eV1+eV2+eV3 = eV1*2 + eV3 
            double v1 = eVolume1_3_ZABOR_BOTTOM(x1, x2, y1, y2, y3, a, x2) - eVolume1_3_ZABOR_BOTTOM(x1, x2, y1, y2, y3, a, x1);
            double v2 = eVolume2_ZABOR_BOTTOM(x1, x2, y1, y2, y3, a);
            double v = v2 + 2.0 * v1;
            return v;
        }
        //=======================================================================================

        //====================объем V2_b======================================
        private static double eVolume2_ZABOR_BOTTOM(double x1, double x2, double y1, double y2, double y3, double a)
        {
            double v2 = (x2 - x1) * (a - 2.0 * y3) * (y3 - 0.5 * y1 - 0.5 * y2);
            return v2;
        }
        //=======================================================================================

        //====================объем V1_b======================================
        private static double eVolume1_3_ZABOR_BOTTOM(double x1, double x2, double y1, double y2, double y3, double a, double x)
        {
            double v1 = 0.5 * (y3 - y1) * (y3 - y1) * x - 0.5 * x * x * (y3 - y1) + x * x1 * (y3 - y1) - y1 * x * (y3 - y1) -
                ((x2 - x1) / (6.0 * (y2 - y1))) * (y2 - y1 + (y2 - y1) * (x - x1) / (x2 - x1)) * (y2 - y1 + (y2 - y1) * (x - x1) / (x2 - x1)) *
                (y2 - y1 + (y2 - y1) * (x - x1) / (x2 - x1)) + (y2 - y1) * x * x * x / (3.0 * (x2 - x1)) + 0.5 * x * x * (y2 - y1 - (y2 - y1) * x1 / (x2 - x1)) -
                0.5 * x1 * x * x * (y2 - y1) / (x2 - x1) + x * (x1 * y1 - x1 * y2 + x1 * x1 * (y2 - y1) / (x2 - x1)) + 0.5 * y1 * x * x * (y2 - y1) / (x2 - x1) +
                x * (y2 * y1 - y1 * y1 - (y2 - y1) * x1 * y1 / (x2 - x1));
            return v1;
        }
        //=======================================================================================

        //==============y=k*x+b / возвращaет k=============================================
        private static double k_FunctionLine(double x1, double y1, double x2, double y2)
        {
            return (y2 - y1) / (x2 - x1);
        }
        //=================================================================================

        //==============y=k*x+b / возвращaет b=============================================
        private static double b_FunctionLine(double x1, double y1, double x2, double y2)
        {
            return y1 - x1 * (y2 - y1) / (x2 - x1);
        }
        //=================================================================================

        //==================номер ближайшего X к текущему==================================
        private static int NumNearestX(int NumCurX, double[] pointX, bool[] NoExitPoint, int count, int t)
        {
            if (t != 2)
            {
                int num = -1;
                double delta = 0;
                for (int i = 0; i < count; i++)
                {
                    if (i != NumCurX)
                    {
                        if (NoExitPoint[i] == true)
                        {
                            if (num == -1)
                            {
                                num = i;
                                delta = Math.Abs(pointX[NumCurX] - pointX[i]);
                            }
                            double modul = Math.Abs(pointX[NumCurX] - pointX[i]);
                            if (modul < delta)
                            {
                                delta = modul;
                                num = i;
                            }
                        }
                    }
                }
                return num;
            }
            else
            {
                int num = -1;
                double delta = 0;
                for (int i = 0; i < count - 1; i++)
                {
                    if (i != NumCurX)
                    {
                        if (NoExitPoint[i] == true)
                        {
                            if (num == -1)
                            {
                                num = i;
                                delta = Math.Abs(pointX[NumCurX] - pointX[i]);
                            }
                            double modul = Math.Abs(pointX[NumCurX] - pointX[i]);
                            if (modul < delta)
                            {
                                delta = modul;
                                num = i;
                            }
                        }
                    }
                }
                return num;
            }
        }
        //=======================================================================================

        //====================объем элементарной фигуры для укладки (eV)==========================
        private static double elementarVolume_UKLADKA(double x1, double h1, double x2, double h2, double a)
        {
            //eV = eV1+eV2+eV3 = eV1*2 + eV3 
            double v1 = eVolume1_3_UKLADKA(x1, h1, x2, h2, a, x2) - eVolume1_3_UKLADKA(x1, h1, x2, h2, a, x1);
            double v2 = eVolume2_UKLADKA(x1, h1, x2, h2, a, x2) - eVolume2_UKLADKA(x1, h1, x2, h2, a, x1);
            double v = v2 + 2.0 * v1;
            return v;
        }
        //=======================================================================================

        //=======================================================================================
        private static double eVolume1_3_UKLADKA(double x1, double h1, double x2, double h2, double a, double x)
        {
            double v1 = 0;
            if ((x1 == x2) || ((h1 == 0) && (h2 == 0))) return 0;
            v1 = 0.5 * (h1 * h1 * x + (1.0 / 3.0) * ((h2 - h1) / (x2 - x1)) * (x - x1) * (x - x1) * (x - x1) + h1 * (x - x1) * (x - x1) * ((h2 - h1) / (x2 - x1)));
            return v1;
        }
        //=======================================================================================

        //=======================================================================================
        private static double eVolume2_UKLADKA(double x1, double h1, double x2, double h2, double a, double x)
        {
            double v2 = 0;
            if ((x1 == x2) || ((h1 == 0) && (h2 == 0))) return 0;
            v2 = 2.0 * (h1 - h2) * x * x * x / (3.0 * (x2 - x1)) - (h1 - h2) * x1 * x * x / (x2 - x1) + 0.5 * a * x * x - h1 * x * x - x1 * (h1 - h2) * (x - x1) * (x - x1) / (x2 - x1) -
                            x1 * a * x + 2 * h1 * x1 * x + h1 * (h1 - h2) * (x - x1) * (x - x1) / (x2 - x1) + a * h1 * x - 2.0 * h1 * h1 * x;
            return v2;
        }
        //=======================================================================================

        //====================объем перекрытия при закладке======================================
        private static double VolumeFigure_UKLADKA(double[] pointX, double[] pointY, int count,double A)
        {
            double v = 0;
            for (int i = 0; i < count - 1; i++)
            {
                double x1 = pointX[i];
                double x2 = pointX[i + 1];
                double h1 = pointY[i];
                double h2 = pointY[i + 1];
                if (h1 > h2)
                {
                    double tmpX = x1, tmpH = h1;
                    //		x1 = x2;
                    h1 = h2;
                    //		x2 = tmpX;
                    h2 = tmpH;
                }
                v += elementarVolume_UKLADKA(x1, h1, x2, h2, A);
            }
            return v;
        }
        //=======================================================================================

        //====================объем фигуры при заборе======================================
        private static double VolumeFigure_ZABOR(double[] pointX, double[] pointY, int count,double A)
        {
            double v = 0;
            bool[] NoExitPoint = new bool[count];
            for (int i = 0; i < count; i++)
            {
                NoExitPoint[i] = true;
            }
            int numXmin = numMin(pointX, count, NoExitPoint);
            int numXmax = numMax(pointX, count, NoExitPoint);
            int numCurX = numXmax;

            NoExitPoint[numCurX] = false;
            double[] pointX1 = AddElementInMassive(pointX, count, pointX[numXmin]);
            double[] pointY1 = AddElementInMassive(pointY, count, pointY[numXmin]);
            bool[] NoExitPoint1 = new bool[count + 1];
            for (int i = 0; i < count; i++)
            {
                NoExitPoint1[i] = NoExitPoint[i];
            }
            NoExitPoint1[count] = true;

            for (int i = 0; i < count - 1; i++)
            {
                int near = NumNearestX(numCurX, pointX1, NoExitPoint1, count + 1, 2);
                double k1 = 0, k2 = 0, x1 = 0, x2 = 0, y1_n = 0, y2_n = 0, y3_n = 0, y1_v = 0, y2_v = 0, y3_v = 0, b1 = 0, b2 = 0;
                //1
                if (numCurX <= numXmax && near < numXmax)
                {
                    k1 = k_FunctionLine(pointX1[near], pointY1[near], pointX1[numCurX], pointY1[numCurX]);
                    b1 = b_FunctionLine(pointX1[near], pointY1[near], pointX1[numCurX], pointY1[numCurX]);
                    int numTmp = 0;
                    for (int i1 = numXmax; i1 < count + 1; i1++)
                    {
                        if (NoExitPoint1[i1] == true)
                        {
                            numTmp = i1;
                            break;
                        }
                    }
                    k2 = k_FunctionLine(pointX1[numTmp], pointY1[numTmp], pointX1[numTmp - 1], pointY1[numTmp - 1]);
                    b2 = b_FunctionLine(pointX1[numTmp], pointY1[numTmp], pointX1[numTmp - 1], pointY1[numTmp - 1]);
                    x1 = pointX1[near];
                    x2 = pointX1[numCurX];

                    if (k2 * x2 + b2 > k1 * x1 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x1 + b2, k2 * x2 + b2, k1 * x2 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x1 + b1, k1 * x2 + b1, k1 * x2 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }
                    if (k2 * x1 + b2 > k1 * x2 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x2 + b2, k2 * x1 + b2, k1 * x1 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x2 + b1, k1 * x1 + b1, k1 * x1 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }

                    if (k1 <= 0)
                    {
                        y2_v = y1_v = pointY1[numCurX];
                        y3_v = pointY1[near];
                    }
                    else
                    {
                        y2_v = y1_v = pointY1[near];
                        y3_v = pointY1[numCurX];
                    }

                    if (k2 >= 0)
                    {
                        y1_n = k2 * x1 + b2;
                        y2_n = k2 * x2 + b2;
                    }
                    else
                    {
                        y1_n = k2 * x2 + b2;
                        y2_n = k2 * x1 + b2;
                    }
                    if (k1 <= 0) y3_n = y1_v;
                    else y3_n = y1_v;
                }
                //2
                if (numCurX <= numXmax && near > numXmax)
                {
                    /*int numTmp=0;
                    for(int i=numXmax;i>=0;i--)
                    {
                        if(NoExitPoint1[i]==true)
                        {
                             numTmp = i;
                             break;
                        }
                    }*/
                    k1 = k_FunctionLine(pointX1[numCurX - 1], pointY1[numCurX - 1], pointX1[numCurX], pointY1[numCurX]);
                    b1 = b_FunctionLine(pointX1[numCurX - 1], pointY1[numCurX - 1], pointX1[numCurX], pointY1[numCurX]);
                    k2 = k_FunctionLine(pointX1[near], pointY1[near], pointX1[near - 1], pointY1[near - 1]);
                    b2 = b_FunctionLine(pointX1[near], pointY1[near], pointX1[near - 1], pointY1[near - 1]);
                    x1 = pointX1[near];
                    x2 = pointX1[numCurX];

                    if (k2 * x2 + b2 > k1 * x1 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x1 + b2, k2 * x2 + b2, k1 * x2 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x1 + b1, k1 * x2 + b1, k1 * x2 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }
                    if (k2 * x1 + b2 > k1 * x2 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x2 + b2, k2 * x1 + b2, k1 * x1 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x2 + b1, k1 * x1 + b1, k1 * x1 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }

                    if (k1 <= 0)
                    {
                        y2_v = y1_v = pointY1[numCurX];
                        y3_v = k1 * x1 + b1;
                    }
                    else
                    {
                        y2_v = y1_v = k1 * x1 + b1;
                        y3_v = pointY1[numCurX];
                    }

                    if (k2 >= 0)
                    {
                        y1_n = pointY1[near];
                        y2_n = k2 * x2 + b2;
                    }
                    else
                    {
                        y1_n = k2 * x2 + b2;
                        y2_n = pointY1[near];
                    }
                    if (k1 <= 0) y3_n = y1_v;
                    else y3_n = y1_v;
                }
                //3
                if (numCurX > numXmax && near < numXmax)
                {
                    k1 = k_FunctionLine(pointX1[near], pointY1[near], pointX1[near + 1], pointY1[near + 1]);
                    b1 = b_FunctionLine(pointX1[near], pointY1[near], pointX1[near + 1], pointY1[near + 1]);

                    k2 = k_FunctionLine(pointX1[numCurX], pointY1[numCurX], pointX1[numCurX + 1], pointY1[numCurX + 1]);
                    b2 = b_FunctionLine(pointX1[numCurX], pointY1[numCurX], pointX1[numCurX + 1], pointY1[numCurX + 1]);
                    x1 = pointX1[near];
                    x2 = pointX1[numCurX];

                    if (k2 * x2 + b2 > k1 * x1 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x1 + b2, k2 * x2 + b2, k1 * x2 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x1 + b1, k1 * x2 + b1, k1 * x2 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }
                    if (k2 * x1 + b2 > k1 * x2 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x2 + b2, k2 * x1 + b2, k1 * x1 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x2 + b1, k1 * x1 + b1, k1 * x1 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }

                    if (k1 <= 0)
                    {
                        y2_v = y1_v = k1 * x1 + b1;
                        y3_v = pointY1[near];
                    }
                    else
                    {
                        y2_v = y1_v = pointY1[near];
                        y3_v = k1 * x1 + b1;
                    }

                    if (k2 >= 0)
                    {
                        y1_n = k2 * x1 + b2;
                        y2_n = pointY1[numCurX];
                    }
                    else
                    {
                        y1_n = pointY1[numCurX];
                        y2_n = k2 * x1 + b2;
                    }
                    if (k1 <= 0) y3_n = y1_v;
                    else y3_n = y1_v;
                }
                //4
                if (numCurX > numXmax && near > numXmax)
                {
                    int numTmp = 0;
                    for (int i1 = numXmax; i1 >= 0; i1--)
                    {
                        if (NoExitPoint1[i1] == true)
                        {
                            numTmp = i1;
                            break;
                        }
                    }
                    k1 = k_FunctionLine(pointX1[numTmp], pointY1[numTmp], pointX1[numTmp + 1], pointY1[numTmp + 1]);
                    b1 = b_FunctionLine(pointX1[numTmp], pointY1[numTmp], pointX1[numTmp + 1], pointY1[numTmp + 1]);

                    k2 = k_FunctionLine(pointX1[near], pointY1[near], pointX1[numCurX], pointY1[numCurX]);
                    b2 = b_FunctionLine(pointX1[near], pointY1[near], pointX1[numCurX], pointY1[numCurX]);
                    x1 = pointX1[near];
                    x2 = pointX1[numCurX];

                    if (k2 * x2 + b2 > k1 * x1 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x1 + b2, k2 * x2 + b2, k1 * x2 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x1 + b1, k1 * x2 + b1, k1 * x2 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }
                    if (k2 * x1 + b2 > k1 * x2 + b1)
                    {
                        v += elementarVolume_ZABOR_BOTTOM(x1, x2, k2 * x2 + b2, k2 * x1 + b2, k1 * x1 + b1, A) - elementarVolume_ZABOR_BOTTOM(x1, x2, k1 * x2 + b1, k1 * x1 + b1, k1 * x1 + b1, A);
                        NoExitPoint1[numCurX] = false;
                        numCurX = near;
                        continue;
                    }

                    if (k1 <= 0)
                    {
                        y2_v = y1_v = k1 * x2 + b1;
                        y3_v = k1 * x1 + b1;
                    }
                    else
                    {
                        y2_v = y1_v = k1 * x1 + b1;
                        y3_v = k1 * x2 + b1;
                    }

                    if (k2 >= 0)
                    {
                        y1_n = pointY1[near];
                        y2_n = pointY1[numCurX];
                    }
                    else
                    {
                        y1_n = pointY1[numCurX];
                        y2_n = pointY1[near];
                    }
                    if (k1 <= 0) y3_n = y1_v;
                    else y3_n = y1_v;
                }



                v += elementarVolume_ZABOR_TOP(x1, x2, y1_v, y2_v, y3_v, A) + elementarVolume_ZABOR_BOTTOM(x1, x2, y1_n, y2_n, y3_n, A);
                NoExitPoint1[numCurX] = false;
                numCurX = near;
            }
            return v;
        }
        //=======================================================================================

        //==============динамическое довавление элемента в конец массива===================
        private static double[] AddElementInMassive(double[] x, int count, double elem)
        {
            double[] tmp = new double[count + 1];
            for (int i = 0; i < count; i++)
            {
                tmp[i] = x[i];
            }
            tmp[count] = elem;
            return tmp;
        }
        //=================================================================================
    }
}
